<?php

namespace App\Models\Mongo\Server;

use App\Models\Mongo\BaseMongo;
use App\Common\Helper;
use App\Models\Redis\Control as RedisControl;
use App\Jobs\MongoIndexReset;
// use Illuminate\Support\Carbon;
// use Illuminate\Support\Facades\Queue;
// use Illuminate\Support\Facades\Log;

abstract class BaseServer extends BaseMongo
{

    protected static string $database = '';

    protected static string $table = '';

    protected static array  $index = [];  //索引

    final public static function create(int|string|null $tableAfter = '',  int|string $dbAfter = ''): \MongoDB\Collection|\MongoDB\Database
    {



        $obj = self::createBase($tableAfter, $dbAfter);   //创建MONGODB 对象


        // Log::channel('mongo_index')->error(json_encode(  ['line' => '321' ,'file' => '321' , 'error' => '312' , 'tableAfter' => $tableAfter , 'dbAfter' => $tableAfter ] , JSON_UNESCAPED_UNICODE ));


        if ($obj instanceof \MongoDB\Collection) {  //文档对象

            $key =  $obj->getCollectionName();

            $config = self::getConfig($obj);

            $result =  RedisControl::hGET($key, $config);

            $serializeIdx  = serialize(static::$index);


            //索引发生变化时
            if (!$result  || $result !== $serializeIdx) {   // 大于一条数据的时候才建立索引


                // Queue::later(Carbon::now()->addSecond(20), (new MongoIndexReset(static::class,$tableAfter,$dbAfter))->onConnection('rabbitmq')->onQueue('mongo_index')  );

                // app('queue')->later( Carbon::now()->addSeconds(30) ,(new MongoIndexReset(static::class,$tableAfter,$dbAfter))->onConnection('rabbitmq')->onQueue('mongo_index') );

                dispatch((new MongoIndexReset(static::class, $tableAfter, $dbAfter))->onConnection('rabbitmq')->onQueue('mongo_index'));
            }
        }



        return $obj;
    }


    final public static function createBase(int|string|null $tableAfter = '',  int|string $dbAfter = ''): \MongoDB\Collection|\MongoDB\Database
    {
        if (!static::$database) {
            $arr = explode('\\', static::class);
            $database  =   Helper::toUnderScore(end($arr));
        } else $database  =   static::$database;


        if ($dbAfter !== '')  $database = $database . '_' . $dbAfter;

        if ($tableAfter === '') $table = static::$table;

        else if ($tableAfter !== null)  $table = static::$table . (static::$table ===  '' ?  $tableAfter : '_' . $tableAfter);

        return !isset($table) ? static::connect()->$database  : static::connect()->$database->$table;
    }


    final public static function getConfig(\MongoDB\Collection $obj)
    {

        return ['key' => 'MONGODB_INDEX', 'id' =>  $obj->getDatabaseName()];
    }








    /**
     * @description:    重置所有索引操作
     * @param {null} $tableAfter
     * @param {string} $dbAfter
     * @return {*}
     */
    final public static function resetIndex(int|string|null $tableAfter = '',  int|string $dbAfter = '')
    {

        $collection = self::createBase($tableAfter, $dbAfter);   //创建MONGODB 对象

        if ($collection instanceof \MongoDB\Collection) {  //文档对象

            $key =  $collection->getCollectionName();

            $config = self::getConfig($collection);

            $result =  RedisControl::hGET($key, $config);

            $serializeIdx  = serialize(static::$index);

            //索引发生变化时
            if ((!$result || $result !== $serializeIdx)  &&  $collection->countDocuments() > 0) {   // 大于一条数据的时候才建立索引

                $collection->dropIndexes();                             //删除所有索引

                foreach (static::$index as $val) {

                    if (is_array($val)) {
                        if (array_is_list($val)) {
                            ksort($val[0]);
                            $collection->createIndex($val[0], $val[1] ?? []);
                        } else {
                            ksort($val);
                            $collection->createIndex($val);
                        }
                    }
                }

                RedisControl::hMset([$key => $serializeIdx], $config);   //设置下次进来时

            }
        }
    }
}
